﻿using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;

namespace ZhuXingFamilys
{
    [Transaction(TransactionMode.Manual)]
    public class testcommand : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            Autodesk.Revit.ApplicationServices.Application app = uiApp.Application;
            Document doc = uiApp.ActiveUIDocument.Document;
            UIDocument uidoc = uiApp.ActiveUIDocument;


            //在项目中选中两个构件
            Reference refer_1 = uidoc.Selection.PickObject(ObjectType.Element);
            Element elem_1 = doc.GetElement(refer_1);
            Reference refer_2 = uidoc.Selection.PickObject(ObjectType.Element);
            Element elem_2 = doc.GetElement(refer_2);
            //实体剪切和相交 工程扣减时很有用
            Transaction ts = new Transaction(doc, "cut");
            ts.Start();
            //两个标准族实例的剪切，剪切前判断是否可以剪切
            CutFailureReason res;
            SolidSolidCutUtils.CanElementCutElement(elem_2, elem_1, out res);
            if (res == CutFailureReason.CutAllowed)
                SolidSolidCutUtils.AddCutBetweenSolids(doc, elem_1, elem_2);
            //获取剪切实例的个数
            //ICollection list = SolidSolidCutUtils.GetCuttingSolids(elem_1);
            //判断两个构件是否连接
            if (JoinGeometryUtils.AreElementsJoined(doc, elem_1, elem_2) == true)
            {
                //取消连接
                JoinGeometryUtils.UnjoinGeometry(doc, elem_1, elem_2);
                //取消剪切
                SolidSolidCutUtils.RemoveCutBetweenSolids(doc, elem_1, elem_2);
                //连接
                JoinGeometryUtils.JoinGeometry(doc, elem_1, elem_2);
                //切换连接顺序
                JoinGeometryUtils.SwitchJoinOrder(doc, elem_1, elem_2);
                //获取连接对象的个数
                //ICollection listid = JoinGeometryUtils.GetJoinedElements(doc, elem_1);
            }
            ts.Commit();
            return Result.Succeeded;

            //Transaction trans = new Transaction(doc, "LianJie");//新建一个事务
            //trans.Start();//开始事务

            ////获得所有结构柱图元
            //FilteredElementCollector JGZfilteredElements = new FilteredElementCollector(doc);
            ////新建一个收集器 ‘JGZfilteredElements’
            //JGZfilteredElements.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralColumns);
            //IList<Element> strcloumn = JGZfilteredElements.ToList<Element>();
            ////获得所有结构板图元（同获得所有结构柱图元）
            //FilteredElementCollector BfilteredElements = new FilteredElementCollector(doc);
            //BfilteredElements.OfClass(typeof(Floor));
            ////var strfloorElement = from element in BfilteredElements
            ////                      where element.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "1"
            ////                      select element;
            //IList<Element> floor = BfilteredElements.ToList<Element>();


            ////获得所有结构板图元（同获得所有结构柱图元）
            //FilteredElementCollector MEfilteredElements = new FilteredElementCollector(doc);
            //MEfilteredElements.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_MechanicalEquipment); ;
            ////var MEElement = from element in BfilteredElements
            ////                      where element.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "1"
            ////                      select element;
            //IList<Element> ME = MEfilteredElements.ToList<Element>();


            ////获得所有结构板图元（同获得所有结构柱图元）
            //FilteredElementCollector SEfilteredElements = new FilteredElementCollector(doc);
            //SEfilteredElements.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_SpecialityEquipment); ;
            ////var MEElement = from element in BfilteredElements
            ////                      where element.get_Parameter(BuiltInParameter.DOOR_NUMBER).AsString() == "1"
            ////                      select element;
            //IList<Element> SE = SEfilteredElements.ToList<Element>();
            //MessageBox.Show("该层模型共包含有:\n" + floor.Count  + "个结构板\n" + ME.Count, SE.Count + "个建筑墙\n接下来有福会进行自动扣减,请耐心等待...");

            ////结构柱扣结构板
            //foreach (Element SEcloumn1 in SE)//遍历，从结构柱存储集合取出每一个结构柱
            //{
            //    foreach (Element floor1 in floor)//遍历，从板存储集合取出每一个板
            //    {
            //        QJ(doc, SEcloumn1, floor1);//调用‘QJ’方法（在末尾），‘QJ’方法的功能是连接并扣减模型
            //    }
            //}

            ////结构柱扣结构板
            ////foreach (Element strcloumn1 in strcloumn)//遍历，从结构柱存储集合取出每一个结构柱
            ////{
            ////    foreach (Element floor1 in floor)//遍历，从板存储集合取出每一个板
            ////    {
            ////        QJ(doc, strcloumn1, floor1);//调用‘QJ’方法（在末尾），‘QJ’方法的功能是连接并扣减模型
            ////    }
            ////}

            ////弹出对话框
            //foreach (Element MEcloumn1 in ME)//遍历，从结构柱存储集合取出每一个结构柱
            //{
            //    foreach (Element floor1 in floor)//遍历，从板存储集合取出每一个板
            //    {
            //        QJ(doc,  MEcloumn1, floor1);//调用‘QJ’方法（在末尾），‘QJ’方法的功能是连接并扣减模型
            //    }
            //}
            //trans.Commit();//结束事务并提交
            //return Result.Succeeded;
        }

        //‘QJ’方法，被主程序调用
        public void QJ(Document doc, Element a, Element b)//被调用的扣减程序
        {
            if (JoinGeometryUtils.AreElementsJoined(doc, a, b))//判断a、b是否连接（例：结构柱扣梁中，a、b在这里代表的是结构柱与梁）
            {
                JoinGeometryUtils.UnjoinGeometry(doc, a, b);//a、b若已经连接则取消连接
            }
            try
            {
                JoinGeometryUtils.JoinGeometry(doc, a, b);//连接a、b
                if (!JoinGeometryUtils.IsCuttingElementInJoin(doc, a, b))//判断扣减效果是否为a扣减b（前面的会扣减后面的）
                {
                    JoinGeometryUtils.SwitchJoinOrder(doc, a, b);//否则的话则转换为a扣减b
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }//调用结束，返回扣减成功的命令

    }
}
